// RAP [rh] HeapStatus not supported
///*******************************************************************************
// * Copyright (c) 2005, 2007 IBM Corporation and others.
// * All rights reserved. This program and the accompanying materials
// * are made available under the terms of the Eclipse Public License v1.0
// * which accompanies this distribution, and is available at
// * http://www.eclipse.org/legal/epl-v10.html
// *
// * Contributors:
// *     IBM Corporation - initial API and implementation
// *     Brock Janicyak - brockj@tpg.com.au 
// *     		- Fix for Bug 11142 [HeapStatus] Heap status is updated too frequently
// *          - Fix for Bug 192996 [Workbench] Reduce amount of garbage created by HeapStatus
// *******************************************************************************/
//
//package org.eclipse.ui.internal;
//
//import java.lang.reflect.Method;
//
//import org.eclipse.jface.action.Action;
//import org.eclipse.jface.action.IAction;
//import org.eclipse.jface.action.IMenuListener;
//import org.eclipse.jface.action.IMenuManager;
//import org.eclipse.jface.action.MenuManager;
//import org.eclipse.jface.preference.IPreferenceStore;
//import org.eclipse.jface.resource.ImageDescriptor;
//import org.eclipse.jface.util.IPropertyChangeListener;
//import org.eclipse.jface.util.PropertyChangeEvent;
//import org.eclipse.osgi.util.NLS;
//import org.eclipse.swt.SWT;
//import org.eclipse.swt.custom.BusyIndicator;
//import org.eclipse.swt.graphics.Color;
//import org.eclipse.swt.graphics.GC;
//import org.eclipse.swt.graphics.Image;
//import org.eclipse.swt.graphics.Point;
//import org.eclipse.swt.graphics.Rectangle;
//import org.eclipse.swt.widgets.Canvas;
//import org.eclipse.swt.widgets.Composite;
//import org.eclipse.swt.widgets.Display;
//import org.eclipse.swt.widgets.Event;
//import org.eclipse.swt.widgets.Listener;
//import org.eclipse.swt.widgets.Menu;
//
///**
// * The Heap Status control, which shows the heap usage statistics in the window trim.
// * 
// * @since 3.1
// */
//public class HeapStatus extends Composite {
//
//	private boolean armed;
//	private Image gcImage;
//	private Color bgCol, usedMemCol, lowMemCol, freeMemCol, topLeftCol, bottomRightCol, sepCol, textCol, markCol, armCol;  
//    private Canvas button;
//	private IPreferenceStore prefStore;
//	private int updateInterval;
//	private boolean showMax;
//    private long totalMem;
//    private long prevTotalMem = -1L;
//    private long prevUsedMem = -1L;
//    private boolean hasChanged;
//    private long usedMem;
//    private long mark = -1;
//    // start with 12x12
//	private Rectangle imgBounds = new Rectangle(0,0,12,12);
//	private long maxMem = Long.MAX_VALUE;
//	private boolean maxMemKnown;
//	private float lowMemThreshold = 0.05f;
//	private boolean showLowMemThreshold = true;
//	private boolean updateTooltip = false;
//	
//    private final Runnable timer = new Runnable() {
//        public void run() {
//            if (!isDisposed()) {
//                updateStats();
//                if (hasChanged) {
//                	if (updateTooltip) {
//                		updateToolTip();
//                	}
//                    redraw();
//                    hasChanged = false;
//                }
//                getDisplay().timerExec(updateInterval, this);
//            }
//        }
//    };
//    
//    private final IPropertyChangeListener prefListener = new IPropertyChangeListener() {
//		public void propertyChange(PropertyChangeEvent event) {
//			if (IHeapStatusConstants.PREF_UPDATE_INTERVAL.equals(event.getProperty())) {
//				setUpdateIntervalInMS(prefStore.getInt(IHeapStatusConstants.PREF_UPDATE_INTERVAL));
//			}
//			else if (IHeapStatusConstants.PREF_SHOW_MAX.equals(event.getProperty())) {
//				showMax = prefStore.getBoolean(IHeapStatusConstants.PREF_SHOW_MAX);
//			}
//		}
//	};
//
//    /**
//     * Creates a new heap status control with the given parent, and using
//     * the given preference store to obtain settings such as the refresh
//     * interval.
//     * 
//     * @param parent the parent composite
//     * @param prefStore the preference store
//     */
//	public HeapStatus(Composite parent, IPreferenceStore prefStore) {
//		super(parent, SWT.NONE);
//
//		maxMem = getMaxMem();
//		maxMemKnown = maxMem != Long.MAX_VALUE;
//
//        this.prefStore = prefStore;
//        prefStore.addPropertyChangeListener(prefListener);
//        
//        setUpdateIntervalInMS(prefStore.getInt(IHeapStatusConstants.PREF_UPDATE_INTERVAL));
//        showMax = prefStore.getBoolean(IHeapStatusConstants.PREF_SHOW_MAX);
//		
//        button = new Canvas(this, SWT.NONE);
//        button.setToolTipText(WorkbenchMessages.HeapStatus_buttonToolTip);
//        
//		ImageDescriptor imageDesc = WorkbenchImages.getWorkbenchImageDescriptor("elcl16/trash.gif"); //$NON-NLS-1$
//		gcImage = imageDesc.createImage();
//		if (gcImage != null) {
//			imgBounds = gcImage.getBounds();
//		}
//		Display display = getDisplay();
//		usedMemCol = display.getSystemColor(SWT.COLOR_INFO_BACKGROUND);
//		lowMemCol = new Color(display, 255, 70, 70);  // medium red 
//		freeMemCol = new Color(display, 255, 190, 125);  // light orange
//		bgCol = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
//		sepCol = topLeftCol = armCol = display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
//		bottomRightCol = display.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
//		markCol = textCol = display.getSystemColor(SWT.COLOR_INFO_FOREGROUND);
//		
//		createContextMenu();
//		
//        Listener listener = new Listener() {
//
//            public void handleEvent(Event event) {
//                switch (event.type) {
//                case SWT.Dispose:
//                	doDispose();
//                    break;
//                case SWT.Resize:
//                    Rectangle rect = getClientArea();
//                    button.setBounds(rect.width - imgBounds.width - 1, 1, imgBounds.width, rect.height - 2);
//                    break;
//                case SWT.Paint:
//                    if (event.widget == HeapStatus.this) {
//                    	paintComposite(event.gc);
//                    }
//                    else if (event.widget == button) {
//                        paintButton(event.gc);
//                    }
//                    break;
//                case SWT.MouseUp:
//                    if (event.button == 1) {
//                        gc();
//                        arm(false);
//                    }
//                    break;
//                case SWT.MouseDown:
//                    if (event.button == 1) {
//	                    if (event.widget == HeapStatus.this) {
//							setMark();
//						} else if (event.widget == button) {
//							arm(true);
//						}
//                    }
//                    break;
//                case SWT.MouseEnter:
//                	HeapStatus.this.updateTooltip = true;
//                	updateToolTip();
//                	break;
//                case SWT.MouseExit:
//                    if (event.widget == HeapStatus.this) {
//                    	HeapStatus.this.updateTooltip = false;
//					} else if (event.widget == button) {
//						arm(false);
//					}
//                    break;
//                }
//            }
//
//        };
//        addListener(SWT.Dispose, listener);
//        addListener(SWT.MouseDown, listener);
//        addListener(SWT.Paint, listener);
//        addListener(SWT.Resize, listener);
//        addListener(SWT.MouseEnter, listener);
//        addListener(SWT.MouseExit, listener);
//        button.addListener(SWT.MouseDown, listener);
//        button.addListener(SWT.MouseExit, listener);
//        button.addListener(SWT.MouseUp, listener);
//        button.addListener(SWT.Paint, listener);
//
//		// make sure stats are updated before first paint
//		updateStats();
//
//        getDisplay().asyncExec(new Runnable() {
//			public void run() {
//				if (!isDisposed()) {
//					getDisplay().timerExec(updateInterval, timer);
//				}
//			}
//		});
//   	}
//
//	/**
//	 * Returns the maximum memory limit, or Long.MAX_VALUE if the max is not known.
//	 */
//	private long getMaxMem() {
//		long max = Long.MAX_VALUE;
//		try {
//			// Must use reflect to allow compilation against JCL/Foundation
//			Method maxMemMethod = Runtime.class.getMethod("maxMemory", new Class[0]); //$NON-NLS-1$
//			Object o = maxMemMethod.invoke(Runtime.getRuntime(), new Object[0]);
//			if (o instanceof Long) {
//				max = ((Long) o).longValue();
//			}
//		}
//		catch (Exception e) {
//			// ignore if method missing or if there are other failures trying to determine the max
//		}
//		return max;
//	}
//	
//	private void setUpdateIntervalInMS(int interval) {
//		updateInterval = Math.max(100, interval);
//	}
//
//	private void doDispose() {
//        prefStore.removePropertyChangeListener(prefListener);
//    	if (gcImage != null) {
//			gcImage.dispose();
//		}
//       
//        if (lowMemCol != null) {
//			lowMemCol.dispose();
//		}
//        if (freeMemCol != null) {
//			freeMemCol.dispose();
//		}
//	}
//
//	/* (non-Javadoc)
//	 * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)
//	 */
//	public Point computeSize(int wHint, int hHint, boolean changed) {
//        GC gc = new GC(this);
//        Point p = gc.textExtent(WorkbenchMessages.HeapStatus_widthStr);
//        int height = imgBounds.height;
//        // choose the largest of 
//        // 	- Text height + margins
//        //	- Image height + margins
//        //	- Default Trim heightin 
//        height = Math.max(height, p.y) + 4;
//        height = Math.max(TrimUtil.TRIM_DEFAULT_HEIGHT, height);
//        gc.dispose();
//		return new Point(p.x + 15, height);
//	}
//	
//    private void arm(boolean armed) {
//        if (this.armed == armed) {
//			return;
//		}
//        this.armed = armed;
//        button.redraw();
//        button.update();
//    }
//
//    /**
//     * Creates the context menu
//     */
//    private void createContextMenu() {
//        MenuManager menuMgr = new MenuManager();
//        menuMgr.setRemoveAllWhenShown(true);
//        menuMgr.addMenuListener(new IMenuListener() {
//			public void menuAboutToShow(IMenuManager menuMgr) {
//				fillMenu(menuMgr);
//			}
//		});
//        Menu menu = menuMgr.createContextMenu(this);
//        setMenu(menu);
//    }
//    
//    private void fillMenu(IMenuManager menuMgr) {
//        menuMgr.add(new SetMarkAction());
//        menuMgr.add(new ClearMarkAction());
//        menuMgr.add(new ShowMaxAction());
//        menuMgr.add(new CloseHeapStatusAction());
////        if (isKyrsoftViewAvailable()) {
////        	menuMgr.add(new ShowKyrsoftViewAction());
////        }
//    }
//
//    /**
//     * Sets the mark to the current usedMem level. 
//     */
//    private void setMark() {
//    	updateStats();  // get up-to-date stats before taking the mark
//        mark = usedMem;
//        hasChanged = true;
//        redraw();
//    }
//
//    /**
//     * Clears the mark. 
//     */
//    private void clearMark() {
//        mark = -1;
//        hasChanged = true;
//        redraw();
//    }
//    
//    private void gc() {
//    	BusyIndicator.showWhile(getDisplay(), new Runnable() {
//			public void run() {
//				Thread t = new Thread() {
//					public void run() {
//						busyGC();
//					}};
//				t.start();
//				while(t.isAlive()) {
//					try {
//						Display d = getDisplay();
//						while(d != null && !d.isDisposed() && d.readAndDispatch()) {
//							// loop
//						}
//						t.join(10);
//					} catch (InterruptedException e) {
//						Thread.currentThread().interrupt();
//					}
//				}
//			}
//		});
//    }
//
//    private void busyGC() {
//        for (int i = 0; i < 2; ++i) {
//	        System.gc();
//	        System.runFinalization();
//        }
//    }
//    
//    private void paintButton(GC gc) {
//        Rectangle rect = button.getClientArea();
//        
//        if (armed) {
//            gc.setBackground(armCol);
//            gc.fillRectangle(rect.x, rect.y, rect.width, rect.height);
//        }
//        if (gcImage != null) {
//			int by = (rect.height - imgBounds.height) / 2 + rect.y; // button y
//			gc.drawImage(gcImage, rect.x, by);
//        }
//    }
//
//    private void paintComposite(GC gc) {
//		if (showMax && maxMemKnown) {
//			paintCompositeMaxKnown(gc);
//		} else {
//			paintCompositeMaxUnknown(gc);
//		}
//    }
//    
//    private void paintCompositeMaxUnknown(GC gc) {
//        Rectangle rect = getClientArea();
//        int x = rect.x;
//        int y = rect.y;
//        int w = rect.width;
//        int h = rect.height;
//        int bw = imgBounds.width; // button width
//        int dx = x + w - bw - 2; // divider x
//        int sw = w - bw - 3; // status width 
//        int uw = (int) (sw * usedMem / totalMem); // used mem width
//        int ux = x + 1 + uw; // used mem right edge
//        
//        gc.setBackground(bgCol);
//        gc.fillRectangle(rect);
//        gc.setForeground(sepCol);
//		gc.drawLine(dx, y, dx, y + h);
//		gc.drawLine(ux, y, ux, y + h);
//        gc.setForeground(topLeftCol);
//        gc.drawLine(x, y, x+w, y);
//		gc.drawLine(x, y, x, y+h);
//		gc.setForeground(bottomRightCol);
//        gc.drawLine(x+w-1, y, x+w-1, y+h);
//		gc.drawLine(x, y+h-1, x+w, y+h-1);
//		
//		gc.setBackground(usedMemCol);
//        gc.fillRectangle(x + 1, y + 1, uw, h - 2);
//        
//        String s = NLS.bind(WorkbenchMessages.HeapStatus_status, convertToMegString(usedMem), convertToMegString(totalMem));
//        Point p = gc.textExtent(s);
//        int sx = (rect.width - 15 - p.x) / 2 + rect.x + 1;
//        int sy = (rect.height - 2 - p.y) / 2 + rect.y + 1;
//        gc.setForeground(textCol);
//        gc.drawString(s, sx, sy, true);
//        
//        // draw an I-shaped bar in the foreground colour for the mark (if present)
//        if (mark != -1) {
//            int ssx = (int) (sw * mark / totalMem) + x + 1;
//            paintMark(gc, ssx, y, h);
//        }
//    }
//
//    private void paintCompositeMaxKnown(GC gc) {
//        Rectangle rect = getClientArea();
//        int x = rect.x;
//        int y = rect.y;
//        int w = rect.width;
//        int h = rect.height;
//        int bw = imgBounds.width; // button width
//        int dx = x + w - bw - 2; // divider x
//        int sw = w - bw - 3; // status width 
//        int uw = (int) (sw * usedMem / maxMem); // used mem width
//        int ux = x + 1 + uw; // used mem right edge
//        int tw = (int) (sw * totalMem / maxMem); // current total mem width
//        int tx = x + 1 + tw; // current total mem right edge
//        
//        gc.setBackground(bgCol);
//        gc.fillRectangle(rect);
//        gc.setForeground(sepCol);
//		gc.drawLine(dx, y, dx, y + h);
//		gc.drawLine(ux, y, ux, y + h);
//		gc.drawLine(tx, y, tx, y + h);
//        gc.setForeground(topLeftCol);
//        gc.drawLine(x, y, x+w, y);
//		gc.drawLine(x, y, x, y+h);
//		gc.setForeground(bottomRightCol);
//        gc.drawLine(x+w-1, y, x+w-1, y+h);
//		gc.drawLine(x, y+h-1, x+w, y+h-1);
//		
//        if (lowMemThreshold != 0 && ((double)(maxMem - usedMem) / (double)maxMem < lowMemThreshold)) {
//            gc.setBackground(lowMemCol);
//        } else {
//            gc.setBackground(usedMemCol);
//        }
//        gc.fillRectangle(x + 1, y + 1, uw, h - 2);
//        
//        gc.setBackground(freeMemCol);
//        gc.fillRectangle(ux + 1, y + 1, tx - (ux + 1), h - 2);
//
//        // paint line for low memory threshold
//        if (showLowMemThreshold && lowMemThreshold != 0) {
//            gc.setForeground(lowMemCol);
//            int thresholdX = x + 1 + (int) (sw * (1.0 - lowMemThreshold));
//            gc.drawLine(thresholdX, y + 1, thresholdX, y + h - 2);
//        }
//
//        String s = NLS.bind(WorkbenchMessages.HeapStatus_status, 
//				convertToMegString(usedMem), convertToMegString(totalMem));
//        Point p = gc.textExtent(s);
//        int sx = (rect.width - 15 - p.x) / 2 + rect.x + 1;
//        int sy = (rect.height - 2 - p.y) / 2 + rect.y + 1;
//        gc.setForeground(textCol);
//        gc.drawString(s, sx, sy, true);
//        
//        // draw an I-shaped bar in the foreground colour for the mark (if present)
//        if (mark != -1) {
//            int ssx = (int) (sw * mark / maxMem) + x + 1;
//            paintMark(gc, ssx, y, h);
//        }
//    }
//
//	private void paintMark(GC gc, int x, int y, int h) {
//        gc.setForeground(markCol);
//		gc.drawLine(x, y+1, x, y+h-2);
//		gc.drawLine(x-1, y+1, x+1, y+1);
//		gc.drawLine(x-1, y+h-2, x+1, y+h-2);
//	}
//
//    private void updateStats() {
//        Runtime runtime = Runtime.getRuntime();
//        totalMem = runtime.totalMemory();
//        long freeMem = runtime.freeMemory();
//        usedMem = totalMem - freeMem;
//
//        if (convertToMeg(prevUsedMem) != convertToMeg(usedMem)) {
//            prevUsedMem = usedMem;
//            this.hasChanged = true;
//        }
//        
//        if (prevTotalMem != totalMem) {
//            prevTotalMem = totalMem;
//            this.hasChanged = true;
//        }
//    }
//
//    private void updateToolTip() {
//    	String usedStr = convertToMegString(usedMem);
//    	String totalStr = convertToMegString(totalMem);
//    	String maxStr = maxMemKnown ? convertToMegString(maxMem) : WorkbenchMessages.HeapStatus_maxUnknown;
//    	String markStr = mark == -1 ? WorkbenchMessages.HeapStatus_noMark : convertToMegString(mark);
//        String toolTip = NLS.bind(WorkbenchMessages.HeapStatus_memoryToolTip, new Object[] { usedStr, totalStr, maxStr, markStr });
//        if (!toolTip.equals(getToolTipText())) {
//            setToolTipText(toolTip);
//        }
//    }
//	
//    /**
//     * Converts the given number of bytes to a printable number of megabytes (rounded up).
//     */
//    private String convertToMegString(long numBytes) {
//        return NLS.bind(WorkbenchMessages.HeapStatus_meg, new Long(convertToMeg(numBytes)));
//    }
//
//    /**
//     * Converts the given number of bytes to the corresponding number of megabytes (rounded up).
//     */
//	private long convertToMeg(long numBytes) {
//		return (numBytes + (512 * 1024)) / (1024 * 1024);
//	}
//
//
//    class SetMarkAction extends Action {
//        SetMarkAction() {
//            super(WorkbenchMessages.SetMarkAction_text);
//        }
//        
//        public void run() {
//            setMark();
//        }
//    }
//    
//    class ClearMarkAction extends Action {
//        ClearMarkAction() {
//            super(WorkbenchMessages.ClearMarkAction_text);
//        }
//        
//        public void run() {
//            clearMark();
//        }
//    }
//
//    class ShowMaxAction extends Action {
//    	ShowMaxAction() {
//            super(WorkbenchMessages.ShowMaxAction_text, IAction.AS_CHECK_BOX);
//            setEnabled(maxMemKnown);
//            setChecked(showMax);
//        }
//        
//        public void run() {
//            prefStore.setValue(IHeapStatusConstants.PREF_SHOW_MAX, isChecked());
//            redraw();
//        }
//    }
//
//    class CloseHeapStatusAction extends Action{
//    	
//    	CloseHeapStatusAction(){
//    		super(WorkbenchMessages.WorkbenchWindow_close );
//    	}
//    	
//    	/* (non-Javadoc)
//    	 * @see org.eclipse.jface.action.IAction#run()
//    	 */
//    	public void run(){
//    		dispose();
//    	}
//    }
//
////    /**
////     * Returns whether the Kyrsoft memory monitor view is available.
////     * 
////     * @return <code>true</code> if available, <code>false</code> otherwise
////     */
////    private boolean isKyrsoftViewAvailable() {
////        return (Platform.getBundle(IHeapStatusConstants.KYRSOFT_PLUGIN_ID) != null) && PlatformUI.getWorkbench().getViewRegistry().find(IHeapStatusConstants.KYRSOFT_VIEW_ID) != null; 
////    }
////    
////    class ShowKyrsoftViewAction extends Action {
////        ShowKyrsoftViewAction() {
////            super(WorkbenchMessages.ShowKyrsoftViewAction_text);
////        }
////        public void run() {
////            if (!isKyrsoftViewAvailable()) { 
////                MessageDialog.openError(getShell(), WorkbenchMessages.HeapStatus_Error, WorkbenchMessages.ShowKyrsoftViewAction_KyrsoftNotInstalled);
////                return;
////            }
////			IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
////            IWorkbenchPage page = window == null ? null : window.getActivePage();
////            if (page == null) {
////                MessageDialog.openError(getShell(), WorkbenchMessages.HeapStatus_Error, WorkbenchMessages.ShowKyrsoftViewAction_OpenPerspectiveFirst);
////                return;
////            }
////            try {
////                page.showView(IHeapStatusConstants.KYRSOFT_VIEW_ID);
////            }
////            catch (PartInitException e) {
////                String msg = WorkbenchMessages.ShowKyrsoftViewAction_ErrorShowingKyrsoftView;
////                IStatus status = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, msg, e);
////                ErrorDialog.openError(getShell(), WorkbenchMessages.HeapStatus_Error, msg, status);
////            }
////            
////        }
////    }
//
//}
//
